Skip to content

feat(jobs): add Jobs.stop() method [PLT-100574]#337

Merged
ninja-shreyash merged 8 commits intomainfrom
feat/sdk-plt-100574
Apr 21, 2026
Merged

feat(jobs): add Jobs.stop() method [PLT-100574]#337
ninja-shreyash merged 8 commits intomainfrom
feat/sdk-plt-100574

Conversation

@ninja-shreyash
Copy link
Copy Markdown
Contributor

@ninja-shreyash ninja-shreyash commented Mar 30, 2026

Method Added

Layer Method Signature
Service jobs.stop() stop(jobKeys: string[], folderId: number, options?: JobStopOptions): Promise<void>
Bound job.stop() stop(options?: JobStopOptions): Promise<void>

Endpoint Called

Method HTTP Endpoint OAuth Scope
stop() (resolve keys) GET /odata/Jobs (via getAll with $filter=key in (...)) OR.Jobs
stop() (stop jobs) POST /odata/Jobs/UiPath.Server.Configuration.OData.StopJobs OR.Jobs
  • Extends FolderScopedService — sets X-UIPATH-OrganizationUnitId header
  • Composite method: resolves UUID keys → integer IDs via getAll(), then calls the StopJobs OData action
  • Keys are chunked (max 50 per query) and resolved in parallel via Promise.all
  • Returns Promise<void> — succeeds silently or throws typed errors on failure

Example Usage

import { Jobs, StopStrategy } from '@uipath/uipath-typescript/jobs';

const jobs = new Jobs(sdk);

// Stop a single job with default soft stop
await jobs.stop([<jobKey>], <folderId>);

// Force-kill multiple jobs
await jobs.stop(
  [<jobKey1>, <jobKey2>],
  <folderId>,
  { strategy: StopStrategy.Kill }
);

// Stop via bound method on a job response
const allJobs = await jobs.getAll({ folderId: <folderId> });
const runningJob = allJobs.items.find(j => j.state === 'Running');
if (runningJob) {
  await runningJob.stop();
}

API Response vs SDK Response

Composition flow

stop(jobKeys, folderId, options?)
  │
  ├─ empty array? → return immediately
  │
  ├─ validate folderId
  │
  ├─ resolveJobKeys(jobKeys, folderId)
  │   ├─ deduplicate keys
  │   ├─ chunk into batches of 50
  │   ├─ Promise.all: getAll({ filter: "key in (...)", select: "id,key" }) per chunk
  │   ├─ build keyToIdMap from responses
  │   └─ throw ValidationError if any keys not found
  │
  └─ stopJobsByIds(jobIds, strategy, headers)
      └─ POST /odata/Jobs/UiPath.Server.Configuration.OData.StopJobs
         body: { jobIds: [...], strategy: "SoftStop" | "Kill" }

Types

Type Purpose
JobStopOptions Optional strategy param (SoftStop or Kill)
StopStrategy Enum — re-exported from jobs.types.ts for subpath import

Additional Changes

  • api-client.ts: Replaced content-length: 0 header check with body-based empty response detection (response.text() → check empty → JSON.parse)
  • StopStrategy re-export: Re-exported from jobs.types.ts so the barrel export * picks it up — removed direct export from jobs/index.ts

Files

Area Files
Endpoint src/utils/constants/endpoints/orchestrator.ts
Types src/models/orchestrator/jobs.types.ts
Constants src/models/orchestrator/jobs.constants.ts
Models src/models/orchestrator/jobs.models.ts
Service src/services/orchestrator/jobs/jobs.ts
Core src/core/http/api-client.ts
Unit tests tests/unit/services/orchestrator/jobs.test.ts (33 tests), tests/unit/models/orchestrator/jobs.test.ts (8 tests)
Integration tests tests/integration/shared/orchestrator/jobs.integration.test.ts (10 tests)
Test utils tests/utils/constants/jobs.ts
Docs docs/oauth-scopes.md, agent_docs/rules.md

Refs PLT-100574

Comment thread src/services/orchestrator/jobs/jobs.ts Outdated
Comment thread src/services/orchestrator/jobs/jobs.ts Outdated
Comment thread tests/integration/shared/orchestrator/jobs.integration.test.ts Outdated
Comment thread src/models/orchestrator/jobs.models.ts
@ninja-shreyash
Copy link
Copy Markdown
Contributor Author

@claude pls add OR.Jobs.Write along with OR.Jobs for Jobs stop() method

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 14, 2026

Claude finished @ninja-shreyash's task in 57s —— View job


Adding OR.Jobs.Write scope to Jobs stop() method

  • Read relevant files to find all scope references
  • Update docs/oauth-scopes.md
  • Commit and push changes

Done. Updated docs/oauth-scopes.md line 18:

-| `stop()` | `OR.Jobs` |
+| `stop()` | `OR.Jobs` or `OR.Jobs.Write` |

This follows the same pattern as Processes.start() which also shows OR.Jobs or OR.Jobs.Write, and aligns with the general convention for write-operation scopes in the SDK.
·

Comment thread tests/unit/services/orchestrator/jobs.test.ts
Comment thread tests/integration/shared/orchestrator/jobs.integration.test.ts Outdated
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 15, 2026

Review summary

Two new findings this run (four prior unresolved threads unchanged):

New — unit test: chunking code path untested
Line 628 in the unit test file — All tests in the stop describe use at most 2 unique keys, so the for loop in resolveJobKeys that chunks keys into batches of 50 is never exercised past a single iteration. The multi-chunk path (> 50 unique keys, two get calls, result merging) needs its own test.

New — integration test: spurious folderId guard on empty-array test
Lines 228-233 in the integration test file — stop([], folderId) returns before ever reading folderId, so the guard causes the test to silently skip in unconfigured environments even though it needs no real credentials. Replace with stop([], 0) and remove the guard.

Comment thread tests/integration/shared/orchestrator/jobs.integration.test.ts Outdated
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 15, 2026

Review summary

One new finding this run (all six prior threads were resolved and confirmed fixed):

New — integration test: OData filter uses wrong field casing
Line 202 in tests/integration/shared/orchestrator/jobs.integration.test.ts"State eq 'Running'" uses PascalCase State (raw API casing), but the Jobs service transforms responses with pascalToCamelCaseKeys() so the SDK-facing field is state. Per the OData convention in agent_docs/conventions.md, filter values should use the SDK response casing: "state eq 'Running'".

Comment thread src/services/orchestrator/jobs/jobs.ts
Comment thread src/services/orchestrator/jobs/jobs.ts Outdated
Comment thread tests/integration/shared/orchestrator/jobs.integration.test.ts Outdated
Comment thread src/services/orchestrator/jobs/jobs.ts Outdated
Comment thread src/models/orchestrator/jobs.models.ts
Comment thread src/services/orchestrator/jobs/jobs.ts Outdated
Comment thread src/services/orchestrator/jobs/jobs.ts Outdated
Comment thread src/models/orchestrator/jobs.models.ts Outdated
Comment thread docs/oauth-scopes.md Outdated
Comment thread src/models/orchestrator/jobs.types.ts Outdated
ninja-shreyash and others added 4 commits April 20, 2026 14:02
Add stop method to the Jobs service that stops one or more jobs by their
UUID keys. Resolves keys to integer IDs in batches of 50, then calls the
StopJobs OData action. Supports SoftStop and Kill strategies.

Also adds text responseType handling to api-client for endpoints returning
empty 200 responses.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…gration test

Co-authored-by: Shreyash <ninja-shreyash@users.noreply.github.com>
Comment thread src/core/http/api-client.ts Outdated
Comment thread tests/utils/constants/jobs.ts Outdated
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 20, 2026

Review summary

Two new findings this run (all prior resolved threads confirmed fixed):

dead code: TEXT response handler — api-client.ts line 111
The RESPONSE_TYPES.TEXT handler block is never triggered. Nothing in this PR passes responseType: RESPONSE_TYPES.TEXT, and the empty-200 case is already handled by the content-length: 0 check above it. Should be removed (or one of the two approaches replaced with the other).

test constant duplicates production constant — tests/utils/constants/jobs.ts line 37
KEY_RESOLUTION_CHUNK_SIZE: 50 duplicates JOB_KEY_RESOLUTION_CHUNK_SIZE from jobs.constants.ts. If the production value changes, the multi-chunk boundary test silently stops exercising the right boundary. The unit test should import JOB_KEY_RESOLUTION_CHUNK_SIZE directly instead.

Comment thread src/services/orchestrator/jobs/jobs.ts Outdated
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 20, 2026

Review summary

One new finding this run (all prior resolved threads confirmed fixed):

New — OData filter and select use PascalCase instead of camelCase
src/services/orchestrator/jobs/jobs.ts lines 324-329 — The private resolveJobKeys method constructs the filter as Key in (...) and passes $select: 'Id,Key' using raw API PascalCase. Per conventions, OData query values must use SDK response casing (camelCase for services with pascalToCamelCaseKeys()) even for internal calls. Should be key in (...) and $select: 'id,key'. The unit test assertions at tests/unit/services/orchestrator/jobs.test.ts lines 525-526 need the same fix.

Comment thread src/services/orchestrator/jobs/index.ts Outdated
Comment thread docs/oauth-scopes.md
Comment thread src/core/http/api-client.ts Outdated
Comment thread src/core/http/api-client.ts Outdated
Comment thread src/models/orchestrator/jobs.constants.ts Outdated
Comment thread src/models/orchestrator/jobs.models.ts
Comment thread src/models/orchestrator/jobs.types.ts Outdated
Comment thread src/services/orchestrator/jobs/jobs.ts
Comment thread src/models/orchestrator/jobs.types.ts
Comment thread src/services/orchestrator/jobs/jobs.ts Outdated
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 20, 2026

✅ No issues found. Checked for bugs and CLAUDE.md compliance.

Comment thread src/models/orchestrator/jobs.models.ts Outdated
Co-authored-by: Shreyash <ninja-shreyash@users.noreply.github.com>
@sonarqubecloud
Copy link
Copy Markdown

Comment thread src/services/orchestrator/jobs/jobs.ts
Comment thread src/models/orchestrator/jobs.types.ts
@ninja-shreyash ninja-shreyash merged commit 9ecd22d into main Apr 21, 2026
26 of 27 checks passed
@ninja-shreyash ninja-shreyash deleted the feat/sdk-plt-100574 branch April 21, 2026 08:34
@ninja-shreyash ninja-shreyash mentioned this pull request Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants